<?php
/**
* 描述：TRYPHP运行模式。
*/
if(!defined('TRYPHP_MODEL')){
    define('TRYPHP_MODEL','rewrite');
}

/**
* 描述：php.buffer检设。
*/
if(!ini_get('output_buffering')){
    ob_start(NULL,4096);
}

/**
* 描述：导入配置文件。
*/
include('config.php');

/**
* 描述：导入核心文构件。
*/
include('function.php');
include('error.php');
include('route.php');
include('database.php');
include('controller.php');
include('template.php');
include('model.php');

/**
* 描述：测检配置项。
*/
if(!defined('TRYPHP_MODEL')){
    Error::Cast('TryPHP配置错误，配置项“调试开关”未设置。配置项字面量：TRYPHP_DEBUG。');
}
if(!defined('TRYPHP')){
    Error::Cast('TryPHP配置错误，配置项“网站开关”未设置。配置项字面量：TRYPHP。');
}
if(!defined('TRYPHP_DEBUG')){
    Error::Cast('TryPHP配置错误，配置项“调试开关”未设置。配置项字面量：TRYPHP_DEBUG。');
}
if(!defined('TRYPHP_ROUTE_PROTOCOL')){
    Error::Cast('TryPHP配置错误，配置项“路由协议”未设置。配置项字面量：TRYPHP_ROUTE_PROTOCOL。');
}
else{
    if('common'===TRYPHP_MODEL&&'static'===TRYPHP_ROUTE_PROTOCOL){
        Error::Cast('TryPHP配置错误，配置项“路由协议”的值不适用，TryPHP运行环境为common，请不要指定协议为static，请修改配置值以适用运行环境。配置项字面量：TRYPHP_ROUTE_PROTOCOL。');
    }
}
if(!defined('TRYPHP_DEFAULT_APPLICATION')){
    Error::Cast('TryPHP配置错误，配置项“默认应用”未设置。配置项字面量：TRYPHP_DEFAULT_APPLICATION。');
}
if(!defined('TRYPHP_DEFAULT_CONTROLLER')){
    Error::Cast('TryPHP配置错误，配置项“默认控制器”未设置。配置项字面量：TRYPHP_DEFAULT_CONTROLLER。');
}
if(!defined('TRYPHP_ROUTE_PROTOCOLOPTIONS_COMMON_PARAMETERNAME_APPLICATION')){
    Error::Cast('TryPHP配置错误，配置项“COMMON协议参数名-应用”未设置。配置项字面量：TRYPHP_ROUTE_PROTOCOLOPTIONS_COMMON_PARAMETERNAME_APPLICATION。');
}
if(!defined('TRYPHP_ROUTE_PROTOCOLOPTIONS_COMMON_PARAMETERNAME_CONTROLLER')){
    Error::Cast('TryPHP配置错误，配置项“COMMON协议参数名-控制器”未设置。配置项字面量：TRYPHP_ROUTE_PROTOCOLOPTIONS_COMMON_PARAMETERNAME_CONTROLLER。');
}
if(!defined('TRYPHP_ROUTE_PROTOCOLOPTIONS_COMMON_PARAMETERNAME_METHOD')){
    Error::Cast('TryPHP配置错误，配置项“COMMON协议参数名-方法”未设置。配置项字面量：TRYPHP_ROUTE_PROTOCOLOPTIONS_COMMON_PARAMETERNAME_METHOD。');
}
if(!defined('TRYPHP_ROUTE_PROTOCOLOPTIONS_COMMON_PARAMETERNAME_MODE')){
    Error::Cast('TryPHP配置错误，配置项“COMMON协议参数名-模式”未设置。配置项字面量：TRYPHP_ROUTE_PROTOCOLOPTIONS_COMMON_PARAMETERNAME_MODE。');
}
if(!isset($CLASS)){
    Error::Cast('TryPHP配置错误，配置项“全局类注册标量”未设置。配置项字面量：CLASS。');
}
if(!isset($FUNCTION)){
    Error::Cast('TryPHP配置错误，配置项“全局函数注册标量”未设置。配置项字面量：Function。');
}

/**
* 描述：抛置全局类自动加载器。
*/
function ____global($name){
    if(isset($GLOBALS['CLASS'][$name])){
        include($GLOBALS['CLASS'][$name]);
    }
}
spl_autoload_register('____global');

/**
* 描述：载入配置项指定的全局函数库。
*/
foreach($FUNCTION as $FunctionFilePath){
    include($FunctionFilePath);
}

/**
* 描述：初始化基要全局标量。
*/
$Root=$_SERVER["DOCUMENT_ROOT"];
$BuildRoot=str_replace('\\','/',dirname(dirname(__FILE__)));
$BuildPath=NULL;
$BuildPathOffset=NULL;
if($Root!==$BuildRoot){
    if(strpos($BuildRoot,$Root)===FALSE){
        if(TRYPHP_PATH_OFFSET){
            $BuildPath=str_replace(TRYPHP_PATH_OFFSET,'',$BuildPath);
        }
    }
    else{
        $BuildPathOffset=str_replace($Root,'',$BuildRoot);
        $BuildPath='/'.substr($BuildPathOffset,1,strlen($BuildPathOffset));
    }
}
$BuildURIPath='http://'.$_SERVER["HTTP_HOST"].$BuildPath;
//~
define('ROOT',$Root);                                                             //文档根目录。
define('BUILD_ROOT',$BuildRoot);                                                  //架设根目录。
define('BUILD_PATH_OFFSET',$BuildPathOffset);                                     //偏移路径。
define('BUILD_PATH',$BuildPath);                                                  //相对的架设根目录。
define('BUILD_URI_PATH',$BuildURIPath);                                           //架设级URI基路径。
define('BUILD_APP_ROOT',BUILD_ROOT.'/'.TRYPHP_APPLICATIONINDENTURE_FOLDERNAME); //应用文档根目录。
define('BUILD_LIBRARY_ROOT',dirname(__FILE__).'/library/');                       //架设级URI基路径。

/**
* 描述：初始化应用基要全局标量。
*/
$Scalar=array(
    'applicationName'=>Route::GetArguments('application'),
    'applicationNameArray'=>explode('_',Route::GetArguments('application')),
    'applicationPath'=>'/'.TRYPHP_APPLICATIONINDENTURE_FOLDERNAME.'/'.str_replace('_','/',Route::GetArguments('application'))
);
//~
define('APP_NAME',$Scalar['applicationName']);                                     //应用用URI基路径。
define('APP_GROUP_ROOT',BUILD_APP_ROOT.'/'.$Scalar['applicationNameArray'][0]);                          //应用文档根目录。
define('APP_ROOT',BUILD_ROOT.$Scalar['applicationPath']);                          //应用文档根目录。
define('APP_PATH',BUILD_PATH.$Scalar['applicationPath']);                          //相对的应用文档根目录。
define('APP_URI_PATH','http://'.$_SERVER["HTTP_HOST"].$Scalar['applicationPath']); //应用用URI基路径。


/**
* 描述：检测网站开关。
*/
if('on'!==TRYPHP){
    Route::Http503();
    return;
}

/**
* 描述：定位控制器程式。
*/
#检测应用目录是否真的存在。不存在就终止程序，并在调试错误开关打开的情况下输出错误信息供于调试。
if(file_exists(APP_ROOT)===FALSE){
    if('on'===strtolower(TRYPHP_DEBUG)){
        Error::Cast(sprintf('找不到应用文件夹，路径是：%s。',APP_ROOT));
    }
    Route::Http406();
    return;
}
#在应用目录存在的情况下，检测具体的控制器文件是否存在，不存在则根据调试错误的开关状态输出信息。
$FileName=str_replace('_','/',Route::GetArguments(Route::INDEX_NAME_CONTROLLER));
$FilePath=APP_ROOT.'/controller/'.$FileName.'.php';
if(file_exists($FilePath)===FALSE){
    if('on'===strtolower(TRYPHP_DEBUG)){
        Error::Cast(sprintf('找不到控制器文件，路径是：%s。',$FilePath));
    }
    Route::Http410();
    return;
}
define('APP_CONTROLLER',str_replace('/','_',$FileName));
define('APP_METHOD',Route::GetArguments(Route::INDEX_NAME_METHOD));
define('APP_MODE',Route::GetArguments(Route::INDEX_NAME_MODE));

/**
* 描述：导入控制器所在应用配置。
*/
#如果应用存在配置文件，根据应用配置文件执行应用配置。
$ApplicationConfigFilePath=APP_ROOT.'/config/application.php';
if(file_exists($ApplicationConfigFilePath)){
    $ApplicationConfig=include($ApplicationConfigFilePath);
    if(gettype($ApplicationConfig)==='array'){
        if(array_key_exists('Initialization',$ApplicationConfig)&&'array'==gettype($ApplicationConfig['Initialization'])){
            foreach($ApplicationConfig['Initialization'] as $value){
                $value();
            }
        }
    }
}
#如果应用存在类库注册配置文件。就根据配置文件，注册相应类库。
$AutoloadConfigFilePath=APP_ROOT.'/config/autoload.php';
if(file_exists($AutoloadConfigFilePath)){
    $classCollection=include($GLOBALS['AutoloadConfigFilePath']);
    if(gettype($classCollection)==='array'){
        foreach($classCollection as $key=>$value){
            $CLASS[$key]=$value;
        }
    }
}

/**
* 描述：创行控制器。
*/
#创建Controller和Model自动加载器。
function ____mvc($name){
    $temp=array_map('strtolower',explode('_',$name));
    $prefixion=$temp[0];
    $filePathPart=implode('/',array_slice($temp,1,count($temp)));
    if($prefixion==='controller'){
        unset($temp[0]);
        $filePath=APP_ROOT.'/controller/'.$filePathPart.'.php';
    }
    elseif($prefixion==='model'){
        $filePath=APP_ROOT.'/model/'.$filePathPart.'.php';
    }
    //--
    if(isset($filePath)){
        include($filePath);
    }
}
spl_autoload_register('____mvc');

/**
* 初始化机理类。
*/
Model::__Initialization();
Controller::__Initialization();

/**
* 按控制器类型执行程式。
*/
switch(Route::GetArguments(Route::INDEX_NAME_MODE)){
    case Controller::MODE_EXEC:
        Controller::Load($FilePath);
    break;
    case Controller::MODE_CLASS:
        //构建类名称。
        $ControllerClassName=NULL;
        foreach(explode('_',Route::GetArguments(Route::INDEX_NAME_CONTROLLER)) as $value){
            $ControllerClassName=($ControllerClassName.'_'.ucfirst($value));
        }
        $ControllerClassName='Controller'.rtrim($ControllerClassName,'_');
        //检测类是否存在。
        Controller::Load($FilePath);
        if(class_exists($ControllerClassName)===TRUE){
            $test=new ReflectionClass($ControllerClassName);
            if($test->isAbstract()){
                if('on'===strtolower(TRYPHP_DEBUG)){
                    Error::Cast(sprintf('不允许实例化虚拟控制器，类名是%s。',$ControllerClassName));
                }
                Route::Http415();
            }
            else{
                 new $ControllerClassName(Route::GetArguments(Route::INDEX_NAME_METHOD));
            }
        }
        else{
            if('on'===strtolower(TRYPHP_DEBUG)){
                Error::Cast(sprintf('找不到控制器类定义，类名是%s。',$ControllerClassName));
            }
            Route::Http417();
        }
    break;
    default:
        if('on'===strtolower(TRYPHP_DEBUG)){
            Error::Cast(sprintf('错误的控制器模式，模式名是%s。',Route::GetArguments(Route::INDEX_NAME_MODE)));
        }
        Route::Http412();
    break;
}